package com.zjs.mq.rabbitmq.service;

import com.rabbitmq.client.Channel;
import com.util.result.Message;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.annotation.Resource;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@Slf4j
@Service
public class RabbitMqService {

    @Resource
    private RabbitTemplate rabbitTemplate;

    /**
     * 通过直连交换机发送消息
     * @return 结果
     */
    public Message sendMessageByDirect(){
        String messageId = String.valueOf(UUID.randomUUID());
        String messageData = "test message, hello!";
        String createTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        Map<String,Object> map=new HashMap<>();
        map.put("messageId",messageId);
        map.put("messageData",messageData);
        map.put("createTime",createTime);
        //将消息携带绑定键值：TestDirectRouting 发送到交换机TestDirectExchange
        log.info("通过直接交换机发送消息：{}", map);
        rabbitTemplate.convertAndSend("TestDirectExchange", "TestDirectRouting", map);
        return Message.success();
    }

    /**
     * 监听TestDirectQueue队列
     * @param message 消息
     */
    @RabbitListener(queues = "TestDirectQueue")
    public void receiveDirectMessage(Map<String,Object> msg, Channel channel, org.springframework.amqp.core.Message message) {
        log.info("Direct消费消息：{}", msg);
        log.info("信道：{}", channel);
        log.info("消息体：{}", message);
        //消费者处理出了问题，需要告诉队列信息消费失败
        try {
            channel.basicNack(message.getMessageProperties().getDeliveryTag(),
                    false, true);
            System.out.println(111);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 通过主题交换机发送消息
     * @return 结果
     */
    public Message sendMessageByTopic(){
        String messageId = String.valueOf(UUID.randomUUID());
        String messageData = "可以匹配";
        String createTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        Map<String,Object> map=new HashMap<>();
        map.put("messageId",messageId);
        map.put("messageData",messageData);
        map.put("createTime",createTime);
        //将消息携带绑定键值：TestTopicRouting 发送到交换机TestTopicExchange
        log.info("通过主题交换机发送消息：{}", map);
        rabbitTemplate.convertAndSend("TestTopicExchange", "TestTopicRouting.可以匹配", map);
        map.put("messageData", "不可以匹配");
        rabbitTemplate.convertAndSend("TestTopicExchange", "TestTopicRouting.不.可以匹配", map);
        return Message.success();
    }

    /**
     * 监听TestTopicQueue队列
     * @param message 消息
     */
    @RabbitListener(queues = "TestTopicQueue")
    public void receiveTopicMessage(Map<String,Object> message) {
        log.info("Topic消费消息：{}", message);
    }

    /**
     * 通过扇形交换机发送消息
     * @return 结果
     */
    public Message sendMessageByFanout(){
        String messageId = String.valueOf(UUID.randomUUID());
        String messageData = "扇形交换机发送消息";
        String createTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        Map<String,Object> map=new HashMap<>();
        map.put("messageId",messageId);
        map.put("messageData",messageData);
        map.put("createTime",createTime);
        log.info("通过扇形交换机发送消息：{}", map);
        rabbitTemplate.convertAndSend("TestFanoutExchange", null, map);
        return Message.success();
    }

    /**
     * 监听TestFanoutQueue1队列
     * @param message 消息
     */
    @RabbitListener(queues = "TestFanoutQueue1")
    public void receiveFanout1Message(Map<String,Object> message) {
        log.info("FanoutQueue1消费消息：{}", message);
    }

    /**
     * 监听TestFanoutQueue2队列
     * @param message 消息
     */
    @RabbitListener(queues = "TestFanoutQueue2")
    public void receiveFanout2Message(Map<String,Object> message) {
        log.info("FanoutQueue2消费消息：{}", message);
    }

    /**
     * 通过首部交换机发送消息
     * @return 结果
     */
    public Message sendMessageByHeaders(){
        String messageData = "首部交换机发送消息";
        log.info("通过首部交换机发送消息：{}", messageData);
        org.springframework.amqp.core.Message ageMsg = MessageBuilder.withBody(messageData.getBytes()).setHeader("age", "18").build();
        rabbitTemplate.convertAndSend("TestHeaderExchange", null, ageMsg);
        return Message.success();
    }

    /**
     * 监听TestHeaderQueue队列
     * @param message 消息
     */
    @RabbitListener(queues = "TestHeaderQueue")
    public void receiveHeadersMessage(byte[] message) {
        log.info("TestHeaderQueue消费消息：{}", new String(message, 0, message.length));
    }

}
